package  
{
	import flash.display.AVM1Movie;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	import flash.display.BitmapData;
	import flash.events.Event;
	import flash.events.EventDispatcher;

	/**
	 * ...
	 * @author Lorenzo Nuvoletta
	 */
	public class Emitter 
	{
		
		public var x:Number;
		public var y:Number;
		public var vx:Number = 0;
		public var vy:Number = 0;
		public var ivx:Number;
		public var ivy:Number;
		public var px:Number;
		public var py:Number;
		public var pvx:Number;
		public var pvy:Number;
		public var pax:Number;
		public var pay:Number;
		public var prx:Number;
		public var pry:Number;
		public var particles:Vector.<Particle>;
		public var lifeTime:uint;
		public var lifeTimeRandom:int;
		public var amounts:uint;
		public var motionInfluence:Number;
		
		public var explosion:Number;
		public var vibration:Number;
		
		public var velocityMin:Number = 0;
		
		public var nozzle:BitmapData;
		
		public var nozzleType:String = 'TRAIL';
		
		//private var trailNozzle:Vector.<EmitPoint>;
		private var trailNozzle:Array;
		
		public function Emitter(x:Number = 0, y:Number = 0, pvx:Number = 0, pvy:Number = 0, pax:Number = 0, pay:Number = 0, prx:Number = 1.0, pry:Number = 1.0, explosion:Number = 0.0, vibration:Number = 0.0, amounts:uint = 1, lifeTime:uint = 1, lifeTimeRandom:int = 0, motionInfluence:Number = 0.0)
		{
			this.x = this.px = x;
			this.y = this.py = y;
			this.pvx = pvx;
			this.pvy = pvy;
			this.pax = pax;
			this.pay = pay;
			this.prx = prx;
			this.pry = pry;
			this.explosion = explosion;
			this.vibration = vibration;
			this.lifeTime = lifeTime;
			this.amounts = amounts;
			this.motionInfluence = motionInfluence;
			this.lifeTimeRandom = lifeTimeRandom;
			particles = new Vector.<Particle>();
			
			nozzle = new BitmapData(100,100);		
			
			trailNozzle = [];
		}

		private var iEmit:uint = 0;
		
		private var r:Number = 0;
		private var evx:Number = 0;
		private var evy:Number = 0;
		private var vibx:Number = 0;
		private var viby:Number = 0;
		private var rv:Number = 0;
		private var ta:Number = 0;
		
		private var e:Number = 0;
		private var ttx:Number = 0;
		private var tty:Number = 0;
		
		private var ti:Number = 0;
		private var tj:Number = 0;
		
		private var lx:Number = 0;
		private var ly:Number = 0;
		
		private var sx:Number = 0;
		private var sy:Number = 0;
		
		private var tvx:Number = 0;
		private var tvy:Number = 0;
		
		private var tmpx:Number = 0;
		private var tmpy:Number = 0;
		private var tmpP:uint = 0;
		
		public function emit():void
		{
			tvx = x - px;
			tvy = y - py;
			
			ivx = tvx * motionInfluence;
			ivy = tvy * motionInfluence;
			
			ta = amounts;//(Math.sqrt(vx * vx + vy * vy) > velocityMin) ? amounts : 0;
			
			
			lx = tvx>0 ? tvx : -tvx;//Math.abs(tvx);
			ly = tvy>0 ? tvy : -tvy;//Math.abs(tvy);
			
			sx = (lx) ? tvx/lx : 1;
			sy = (ly) ? tvy/ly : 1;
			
			ttx = lx*lx;//2 * lx;
			tty = ly*ly;//2 * ly;
			
			ti = 1;
			tj = 0;
			
			if(lx >= ly)
			{
			   // trailNozzle = new Vector.<EmitPoint>(lx,true);
			   trailNozzle = new Array(lx);
				e = lx;
					
				for(ti; ti <= lx; ti++)
				{
					e += tty;
					if(e >= ttx)
					{
						tj++;
						e = e - ttx;
					}
					trailNozzle[ti-1] = new EmitPoint(sx * ti, sy * tj);
				}
			}
			else
			{
				trailNozzle = new Array(ly);
				e = ly;
					
				for(ti; ti <= ly; ti++)
				{
					e += ttx;
					if(e >= tty)
					{
						tj++;
						e = e - tty;
					}
					trailNozzle[ti-1] = new EmitPoint(sx * tj, sy * ti);
				}
			}
			
			var l:int = trailNozzle.length-1;
			for(iEmit = 0; iEmit < ta; iEmit++)
			{
				r =  PI2 * iEmit / amounts;
				evx = Math.cos(r) * explosion;
				evy = Math.sin(r) * explosion;
				
				r = PI2 * Math.random();//360 * Math.random() * Math.PI / 180
				rv = vibration * Math.random();
				
				vibx = rv * Math.sin(r);           
				viby = rv * Math.cos(r);
				
				if(l> 0)
				{
				tmpP = l * Math.random();
				//trailNozzle[0];
				tmpx = trailNozzle[tmpP].x + px;
				tmpy = trailNozzle[tmpP].y + py;
				}
				else
				{
					tmpx = x;
					tmpy = y;
				}
				particles.push(new Particle(tmpx, tmpy, pvx + ivx + evx + vibx , pvy + ivy + evy + viby, pax, pay, prx, pry, lifeTime - int(Math.random() * lifeTimeRandom)));
				
			}          
		}
		
		private const PI2:Number = 2*Math.PI;
		private var iUpdate:int = 0;
		private var pLength:int = 0;
		public function update():void
		{
			vx = x - px;
			vy = y - py;
			px = x;
			py = y;
			
			pLength = particles.length;
			if(pLength == 0) return;
			
			iUpdate = pLength - 1;
			var p:Particle;
			do
			{
				p = particles[iUpdate];
				p.vx += p.ax;
				p.vx *= p.rx;
				p.x += p.vx;
				
				p.vy += p.ay;
				p.vy *= p.ry;
				p.y += p.vy;

				if(p.lifeTime <= 0)
				{
					particles.splice(iUpdate,1);
					continue;
				}
				p.lifeTime--;
			}
			while(iUpdate--);
		}
		
	}

}